<?php
/**
 * Each engineer has a duty to keep the code elegant
 * Created by wolffy.
 * Author @wolffy<13750088090@sina.cn>
 * Date: 2018/8/22
 * Time: 20:37
 */
namespace App\Services\LandingRepaymentC;

class LandingRepaymentCService
{
    protected $landingCApi;
    protected $landingCSelectApi;
    protected $landingCSecret;
    protected $landingCMerchno;
    protected $landingCSubMerchantRegisterNotifyUrl;
    protected $landingCSubMerchantOpenCardReturnUrl;
    protected $landingCSubMerchantOpenCardNotifyUrl;
    protected $landingCConsumeNotifyUrl;
    protected $landingCRepaymentNotifyUrl;
    protected $landingCWithdrawNotifyUrl;

    private $methodname;//接口请求业务类型
    private $orderNo;//订单号
    private $returnUrl;//跳转返回url
    private $notifyUrl;//回调url
    private $truename;//真实姓名
    private $realname;//真实姓名
    private $idCardNo;//身份证号
    private $mobile;//手机号码
    private $bankCardNo;//银行卡号
    private $bankCardCode;//银行卡号
    private $subMerchantNo;//子商户号
    private $amount;//金额
    private $userFee;//用户费率 金额
    private $mcc;//消费类型编号
    private $bankName;//银行名称
    private $personalAddress;//个人地址
    private $transtype;//交易类型
    private $accounttype;//交易类型
    private $accountProperty;//交易类型

    public function __construct()
    {
        $this->landingCApi = config('landingrepaymentc.landing_c_api');//落地c接口
        $this->landingCSelectApi = config('landingrepaymentc.landing_c_select_api');//落地c查询接口
        $this->landingCSecret = config('landingrepaymentc.landing_c_secret');//商户密钥
        $this->landingCMerchno = config('landingrepaymentc.landing_c_merchno');//商户id
        $this->landingCSubMerchantRegisterNotifyUrl = config('landingrepaymentc.landing_c_sub_merchant_register_notify_url');//注册子商户号回调
        $this->landingCSubMerchantOpenCardReturnUrl = config('landingrepaymentc.landing_c_sub_merchant_open_card_return_url');//子商户开卡成功返回url
        $this->landingCSubMerchantOpenCardNotifyUrl = config('landingrepaymentc.landing_c_sub_merchant_open_card_notify_url');//子商户开卡回调
        $this->landingCConsumeNotifyUrl = config('landingrepaymentc.landing_c_consume_notify_url');//消费回调
        $this->landingCRepaymentNotifyUrl = config('landingrepaymentc.landing_c_repayment_notify_url');//还款回调
        $this->landingCWithdrawNotifyUrl = config('landingrepaymentc.landing_c_withdraw_notify_url');//提现回调

    }

    /**
     * 请求参数
     * @return array
     */
    protected function requestParams($transcode = '404', $cardType = 'credit')
    {
        $params =  [
            'transcode' => $transcode,
            'version' => '001',
            'merchno' => $this->landingCMerchno,
            'methodname' => $this->methodname,
            'dsorderid' => $this->orderNo,
            'returnUrl' => $this->returnUrl,
            'notifyUrl' => $this->notifyUrl,
            'name' => $this->truename,
            'username' => $this->realname,
            'idCardNo' => $this->idCardNo,//身份证号
            'mobile' => $this->mobile,
            'bankCardNo' => $this->bankCardNo,
            'bankcard' => $this->bankCardCode,
            'accounttype' => $this->accounttype,
            'accountProperty' => $this->accountProperty,
            'bankName' => $this->bankName,
            'subMerchantNo' => $this->subMerchantNo,//子商户
            'cardType' => $cardType,
            'amount' => $this->amount,
            'userFee' => $this->userFee,
            'mcc' => $this->mcc,
            'transtype' => $this->transtype,
        ];
        if (null == $transcode)
            unset($params['transcode']);
        if (null == $this->methodname)
            unset($params['methodname']);
        if (null == $this->orderNo)
            unset($params['dsorderid']);
        if (null == $this->returnUrl)
            unset($params['returnUrl']);
        if (null == $this->notifyUrl)
            unset($params['notifyUrl']);
        if (null == $this->truename)
            unset($params['name']);
        if (null == $this->realname)
            unset($params['username']);
        if (null == $this->idCardNo)
            unset($params['idCardNo']);
        if (null == $this->mobile)
            unset($params['mobile']);
        if (null == $this->bankCardNo)
            unset($params['bankCardNo']);
        if (null == $this->bankCardCode)
            unset($params['bankcard']);
        if (null == $this->bankName)
            unset($params['bankName']);
        if (null == $this->subMerchantNo)
            unset($params['subMerchantNo']);
        if (null == $cardType)
            unset($params['cardType']);
        if (null == $this->amount)
            unset($params['amount']);
        if (null == $this->userFee)
            unset($params['userFee']);
        if (null == $this->mcc)
            unset($params['mcc']);
        if (null == $this->transtype)
            unset($params['transtype']);
        if (null == $this->accounttype)
            unset($params['accounttype']);
        if (null == $this->accountProperty)
            unset($params['accountProperty']);
        return $params;
    }

    /**
     * 获取接口请求结果
     * @param $param
     * @param $url
     * @return mixed
     */
    protected function getRequestResult($param, $url)
    {
        // 根据key排序数组
        ksort($param);
        // 转换成字符串 格式为：key=valkey2=val2
        $singleStr = $this->toUrlParams($param);
        // 加密字符拼接秘钥进行md5加密，得到签名
        $param['sign'] = md5($singleStr . $this->landingCSecret);
        $client = new \GuzzleHttp\Client(['verify' => false]);
        $response = $client->request('post', $url, ['json' => $param]);
        $json = json_decode($response->getBody()->getContents(), true);
        return $json;
    }

    /**
     * 格式化参数
     * @param $param
     * @return string
     */
    protected function toUrlParams($param){
        $string = '';
        foreach ($param as $k=>$v){
            if(is_array($v)){
                $s = '';
                foreach ($v as $key=>$val){
                    $s .= $key.'=' . $val . ', ';
                }
                $s = substr($s,0,-2);
                $string .= $k . '=' . '{'. $s .'}';
            }else{
                $string .= $k . '=' . $v;
            }
        }
        return $string;
    }

    /**
     * 子商户注册
     * @param $orderNo
     * @param $trueName
     * @param $mobile
     * @param $idCard
     * @param $bankCardNo
     * @param $bankCardName
     * @param $consumeAddress
     * @return mixed
     */
    public function subMerchantRegister($orderNo, $trueName, $mobile, $idCard, $bankCardNo, $bankCardName, $consumeAddress)
    {
        $this->orderNo = $orderNo;
        $this->methodname = 'network';
        $this->notifyUrl = $this->landingCSubMerchantRegisterNotifyUrl;
        $this->truename = $trueName;
        $this->mobile = $mobile;
        $this->idCardNo = $idCard;
        $this->bankCardNo = $bankCardNo;
        $this->bankName = $bankCardName;
        $this->personalAddress = $consumeAddress;
        $dataContent = $this->requestParams();
        $dataContent['subMer'] = [
            'subMerType' => 3,
            'legalName' => $this->truename,//姓名
            'legalMobile' => $this->mobile,//手机号
            'legalIdNo' => $this->idCardNo,//身份证号
            'legalValidityFlag' => 1,//证件号是否为长期
            'legalBankCard' => $this->bankCardNo,//银行卡号
            'legalBankName' => $this->bankName,//银行名称
            'legalBankCardType' => 'credit',//银行卡类型 debit(借记卡)，credit(贷记卡)
            'merOpenName' => $this->truename,//银行卡开卡姓名
            'minSettleAmout' => '2',//起结金额
            'companyAddress' => $this->personalAddress,//个人住宅地址
        ];
        return $this->getRequestResult($dataContent, $this->landingCApi);
    }

    /**
     * 子商户是否注册查询
     * @param $idCard
     * @return mixed
     */
    public function subMerchantRegisterSelect($idCard)
    {
        $this->methodname = 'queryNetwork';
        $this->idCardNo = $idCard;

        $dataContent = $this->requestParams();
        return $this->getRequestResult($dataContent, $this->landingCApi);
    }

    /**
     * 子商户余额查询
     * @param $subMerchantNo
     * @return mixed
     */
    public function subMerchantBalanceSelect($subMerchantNo)
    {
        $this->methodname = 'queryBalance';
        $this->subMerchantNo = $subMerchantNo;

        $dataContent = $this->requestParams();
        return $this->getRequestResult($dataContent, $this->landingCApi);
    }

    /**
     * 子商户开卡
     * @param $orderNo
     * @param $trueName
     * @param $mobile
     * @param $idCard
     * @param $bankCardNo
     * @return mixed
     */
    public function subMerchantOpenCard($orderNo, $subMerchantNo, $trueName, $mobile, $idCard, $bankCardNo)
    {
        $this->methodname = 'openCard';
        $this->orderNo = $orderNo;
        $this->subMerchantNo = $subMerchantNo;
        $this->truename = $trueName;
        $this->mobile = $mobile;
        $this->idCardNo = $idCard;
        $this->bankCardNo = $bankCardNo;
        $this->returnUrl = $this->landingCSubMerchantOpenCardReturnUrl;
        $this->notifyUrl = $this->landingCSubMerchantOpenCardNotifyUrl;

        $dataContent = $this->requestParams();
        return $this->getRequestResult($dataContent, $this->landingCApi);
    }

    /**
     * 子商户消费
     * @param $orderNo
     * @param $subMerchantNo
     * @param $bankCardNo
     * @param $amount
     * @param $userFee
     * @param $mcc
     * @return mixed
     */
    public function subMerchantConsume($orderNo, $subMerchantNo, $bankCardNo, $amount, $userFee, $mcc)
    {
        $this->methodname = 'trade';
        $this->orderNo = $orderNo;
        $this->subMerchantNo = $subMerchantNo;
        $this->bankCardNo = $bankCardNo;
        $this->amount = $amount;
        $this->userFee = $userFee;
        $this->mcc = $mcc;
        $this->notifyUrl = $this->landingCConsumeNotifyUrl;

        $dataContent = $this->requestParams();
        return $this->getRequestResult($dataContent, $this->landingCApi);
    }

    /**
     * 子商户还款
     * @param $orderNo
     * @param $subMerchantNo
     * @param $bankCardNo
     * @param $amount
     * @param $userFee
     * @return mixed
     */
    public function subMerchantRepayment($orderNo, $subMerchantNo, $bankCardNo, $amount, $userFee)
    {
        $this->methodname = 'withdraw';
        $this->orderNo = $orderNo;
        $this->subMerchantNo = $subMerchantNo;
        $this->bankCardNo = $bankCardNo;
        $this->amount = $amount;
        $this->userFee = $userFee;
        $this->notifyUrl = $this->landingCRepaymentNotifyUrl;

        $dataContent = $this->requestParams();
        return $this->getRequestResult($dataContent, $this->landingCApi);
    }

    /**
     * 子商户提现
     * @param $orderNo
     * @param $subMerchantNo
     * @param $bankCardNo
     * @param $amount
     * @param $userFee
     * @return mixed
     */
    public function subMerchantWithdraw($orderNo, $subMerchantNo, $bankCardNo, $amount, $userFee)
    {
        $this->methodname = 'withdraw';
        $this->orderNo = $orderNo;
        $this->subMerchantNo = $subMerchantNo;
        $this->bankCardNo = $bankCardNo;
        $this->amount = $amount;
        $this->userFee = $userFee;
        $this->notifyUrl = $this->landingCWithdrawNotifyUrl;

        $dataContent = $this->requestParams();
        return $this->getRequestResult($dataContent, $this->landingCApi);
    }

    /**
     * 子商户绑卡
     * @param $orderNo
     * @param $subMerchantNo
     * @param $bankCardNo
     * @param $bankCardName
     * @return mixed
     */
    public function subMerchantBindCard($orderNo, $subMerchantNo, $bankCardNo, $bankCardName)
    {
        $this->methodname = 'bindCard';
        $this->orderNo = $orderNo;
        $this->subMerchantNo = $subMerchantNo;
        $this->bankCardNo = $bankCardNo;
        $this->bankName = $bankCardName;
        $dataContent = $this->requestParams();
        return $this->getRequestResult($dataContent, $this->landingCApi);
    }

    /**
     * 代收付查询
     * @param $orderNo
     * @param $transName
     * @return mixed
     */
    public function receiveAndPaymentSelect($orderNo, $transName)
    {
        switch ($transName) {
            //交易
            case 'transaction' :
                $transtype = 55;
                break;
            //提现
            case 'withdraw' :
                $transtype = 56;
                break;
            //开卡
            case 'openCard' :
                $transtype = 57;
                break;
            //绑卡
            case 'bindCard' :
                $transtype = 58;
                break;
            //代付查询
            case 'tradeQuery' :
                $transtype = 20;
                break;
            default :
                $transtype = 55;
                break;
        }
        $this->orderNo = $orderNo;
        $this->transtype = $transtype;

        $dataContent = $this->requestParams('902', '');
        return $this->getRequestResult($dataContent, $this->landingCSelectApi);
    }

    /**
     * 个人账户余额提现
     * @param $orderNo
     * @param $realname
     * @param $bankCardCode
     * @param $amount
     * @param $accounttype
     * @param $accountProperty
     * @return mixed
     *  array:9 [
     * "transcode" => "201"
     * "merchno" => "lmkj25se267f69f"
     * "dsorderid" => "A904416472040453"
     * "sign" => "19ae3ef28dc7d7234d23a774dee0497d"
     * "returncode" => "0001"
     * "errtext" => "交易失败:交易金额小于最小单笔交易金额"
     * "orderid" => "2018090414104000100117971"
     * "currAccountBalance" => 868.39
     * "frozenamount" => 0.0
     * ]
     * array:9 [
     * "transcode" => "201"
     * "merchno" => "lmkj25se267f69f"
     * "dsorderid" => "A904419153224966"
     * "sign" => "20cefab945e3e183c86b39311f3d6144"
     * "returncode" => "0003"
     * "errtext" => "交易处理中"
     * "orderid" => "2018090414150800100118140"
     * "currAccountBalance" => 857.89
     * "frozenamount" => 10.5
     * ]
     */
    public function personalAccountWithdraw($orderNo, $realname, $bankCardCode, $amount, $accounttype, $accountProperty)
    {
        $this->orderNo = $orderNo;
        $this->realname = $realname;
        $this->bankCardCode = $bankCardCode;
        $this->accounttype = $accounttype;
        $this->accountProperty = $accountProperty;
        $this->amount = $amount;
        $dataContent = $this->requestParams('201', '');
        return $this->getRequestResult($dataContent, $this->landingCSelectApi);
    }
}